﻿Public Class UpgradeTools

    'This is used for download
    Private ev As New System.Threading.AutoResetEvent(False)


    Private Sub GotData(ByVal ar As IAsyncResult)
        '-- Callback for BeginRead

        '-- Get the state object associated with this read
        Dim mystate As State = CType(ar.AsyncState, State)
        '-- Get the number of bytes read
        Dim read As Int32 = mystate.InputStream.EndRead(ar)
        If read > 0 Then
            '-- Write the data to the output stream
            mystate.OutputStream.Write(mystate.Data, 0, read)
            '-- begin reading another buffer
            mystate.InputStream.BeginRead(mystate.Data, 0, mystate.Data.Length, AddressOf GotData, mystate)
        Else
            '-- Zero bytes read. We're done. Close the output stream.
            mystate.OutputStream.Close()
            '-- Close the input stream if it's there, and the flag lets us
            If mystate.DontCloseInputStream = False Then
                If Not mystate.InputStream Is Nothing Then
                    mystate.InputStream.Close()
                End If
            End If
            '-- close the response if it's there
            If Not mystate.Response Is Nothing Then
                mystate.Response.Close()
            End If
            '-- Call Set 
            ev.Set()
        End If
    End Sub





    Public Function Download(ByVal Url As String, ByVal FileName As String) As Boolean

        Dim myProxy As New System.Net.WebProxy
        Dim LocalExeDir As String = Microsoft.Win32.Registry.GetValue("HKEY_CURRENT_USER\Formition", "ApplicationRunningPath", "")

        'lets put this somewhere smart, do not overwrite the EXE they know works until it downloads completely
        LocalExeDir = LocalExeDir & "\"

        FileName = LocalExeDir & FileName

        Try
            '-- The state class is a context around the file being downloaded
            Dim mystate As New State
            '-- Create an output stream for the local file
            If Not System.IO.File.Exists(FileName) Then
                If Not System.IO.Directory.Exists(LocalExeDir) Then
                    System.IO.Directory.CreateDirectory(LocalExeDir)
                End If
            End If

            'Download EXE file here 
            mystate.OutputStream = New System.IO.FileStream(FileName, System.IO.FileMode.Create)
            '-- Create a web request from the URL, method = GET
            Dim MyURL As String
            MyURL = Url & "?" & FormatDateTime(Now, DateFormat.LongTime)
            Dim req As System.Net.HttpWebRequest = CType(System.Net.WebRequest.Create(MyURL), System.Net.HttpWebRequest)

            req.Proxy = System.Net.WebProxy.GetDefaultProxy
            req.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials
            System.Net.ServicePointManager.Expect100Continue = False

            req.Method = "GET"
            req.Credentials = System.Net.CredentialCache.DefaultCredentials
            '-- Get the response 

            mystate.Response = CType(req.GetResponse, System.Net.HttpWebResponse)

            '-- Get a reference to the response stream (for downloading)
            mystate.InputStream = mystate.Response.GetResponseStream
            '-- Do an asynchronous read, with a maximum of mystate.data.length number
            '   of bytes read at one time. Call GotData when one buffer has been
            '   filled.

            mystate.InputStream.BeginRead(mystate.Data, 0, mystate.Data.Length, _
              AddressOf GotData, mystate)
            '-- Wait for ev.set, which we call when the last buffer has been received
            ev.WaitOne()
        Catch ex As UnauthorizedAccessException
            Upgrade.Cursor = Cursors.Default
            MsgBox("Access is denied. Unable to download the new version to your hard drive.", MsgBoxStyle.Information)
            Return False
        Catch ex As Exception
            Upgrade.Cursor = Cursors.Default
            MsgBox("An error occurred downloading the latest update. " & ex.Message, MsgBoxStyle.Information)
            Return False
        End Try

        Return True
    End Function

End Class



Public Class State
    '-- receive buffer
    Private _data(8191) As Byte
    Public Property Data() As Byte()
        Get
            Return _data
        End Get
        Set(ByVal Value As Byte())
            _data = Value
        End Set
    End Property

    '-- output stream for file that gets written
    Private _outputstream As IO.FileStream
    Public Property OutputStream() As IO.FileStream
        Get
            Return _outputstream
        End Get
        Set(ByVal Value As IO.FileStream)
            _outputstream = Value
        End Set
    End Property

    '-- input stream for data being downloaded
    Private _inputstream As IO.Stream
    Public Property InputStream() As IO.Stream
        Get
            Return _inputstream
        End Get
        Set(ByVal Value As IO.Stream)
            _inputstream = Value
        End Set
    End Property

    '-- web response
    Private _response As System.Net.HttpWebResponse
    Public Property Response() As System.Net.HttpWebResponse
        Get
            Return _response
        End Get
        Set(ByVal Value As System.Net.HttpWebResponse)
            _response = Value
        End Set
    End Property

    '-- flag for closing the input stream after receiving all data
    Private _dontCloseInputStream As Boolean
    Public Property DontCloseInputStream() As Boolean
        Get
            Return _dontCloseInputStream
        End Get
        Set(ByVal Value As Boolean)
            _dontCloseInputStream = Value
        End Set
    End Property

End Class



